<?php
namespace app\index\model;

use app\api\controller\PublicApi;
use app\common\model\Cards as comCardsModel;
use think\Exception;
use think\facade\Db;
use think\facade\Cache;
use app\common\model\Common;

class Cards extends Common
{
    /**
     * 返回layui的table所需要的格式
     * @param $post
     * @param $user_id
     * @return mixed
     * @throws \think\db\exception\DbException
     */
    public function tableData($post)
    {
        $list_rows  = $post['limit'] ?? config('paginate.list_rows');
        $page       = $post['page'] ?? config('paginate.page');

        $where =[];
        $where[] = ['u.id', '=', $post['user_id']];

        if(isset($post['card_type']) && !empty($post['card_type'])){
            $where[] = ['c.card_type', '=', $post['card_type']];
        }
        if(isset($post['card_num']) && !empty($post['card_num'])){
            $where[] = ['c.card_num', 'like', '%'.$post['card_num'].'%'];
        }
        if(isset($post['remark']) && !empty($post['remark'])){
            $where[] = ['c.remarks', 'like', '%'.$post['remark'].'%'];
        }

        if(isset($post['card_status']) && !empty($post['card_status'])){
            $where[] = ['c.status', '=', $post['card_status']];
        }

        if(isset($post['stime']) && !empty($post['stime'])){
            $start_time = strtotime($post['stime'] . " 00:00:00") - 13*60*60;
            $end_time   = strtotime((empty($post['ltime'])?"2023-12-31":$post['ltime'])  . " 23:59:59") - 13*60*60;
            $where[] = ['c.ctime', 'between', "{$start_time},{$end_time}"];
        }
        $list = Db::name('cards')->alias('c')
            ->leftJoin('user u','u.id=c.user_id')
            ->where($where)
            ->field('c.*')
            ->order('c.ctime desc')
            ->paginate(['list_rows' => $list_rows, 'page' => $page])
            ->toArray();

        return $result = [
            'code'  => 0,
            'msg'   => lang('get info success'),
            'data'  => $list['data'],
            'count' => $list['total'],
        ];
    }

    public function cardsAdd($data , $user_list ,$card_type ,$cardSetList , $bank_type)
    {
        $card_num_for   = $data['card_num'] ?? 1;
        $first_name     = $data['first_name'] ?? 'New';
        $last_name      = $data['last_name'] ?? 'Name';
        $middle_name    = $data['middle_name'] ?? '';
        $spend_limit    = $data['spend_limit'];
        $remarks        = $data['remarks'];
        $cardHeaderType = 'Comdata';
        $user_id        = $user_list['id'];
        //获取改用户信息
        $user_name      = $user_list['username'];
        $open_amount        = $cardSetList[$bank_type][$card_type]['open_amount'];
        $server_amount_db   = $cardSetList[$bank_type][$card_type]['rate_fund'];

        //对firstname和lastname进行优化
        $first_name_up  = $first_name;
        if(strlen($first_name) == 1){
            $first_name_up = $first_name . $first_name . $first_name;
        }else if(strlen($first_name) == 2){
            $first_name_up = $first_name . substr($first_name , 1,1);
        }

        $last_name_up  = $last_name;
        if(strlen($last_name) == 1){
            $last_name_up = $last_name . $last_name . $last_name;
        }else if(strlen($last_name) == 2){
            $last_name_up = $last_name . substr($last_name , 1,1);
        }

        $redis_key_name     = 'user_card_add_' . $user_name;
        //增加进程是否开始，防止重复建卡 //并且时间时间是60秒
        Cache::store('redis')->set($redis_key_name, getUtcTime() , 2);

        //银3禁用mid黑名单
        $getDelKey = getSetting('mid_black_list');
        $key_array = explode(',' , $getDelKey);

        //增加559666禁用的mid
        if($card_type == 559666){
            $getMidValue = getSetting('tran_ice_mid');
            $mid_array = explode(',' , $getMidValue);
            //合并禁用mid
            $key_array = array_merge($key_array , $mid_array);
        }

        $success_num = 0;
        for($i=0;$i< $card_num_for;$i++){
            $create_time = getUtcTime();
            //$set_name custom_name=自定义姓名 | random_name=随机行么
            $card_memo  = "CE" . getRandNumber(0,9,6) . substr($create_time , -6) ;
            $card_type_new  = $card_type;
            if($bank_type == 3){
                $exp_time = date('Y-m-01',strtotime('+23 month'));
                $create_card_param      = [
                    "user_id"       => $user_id,
                    "action_type"   => "addCard",
                    "request_data"  => [
                        "MerchantGuid"      => "6423ae42-1628-4ca1-a5fb-830da34177de",
                        "FirstName"         => $first_name_up,
                        "LastName"         => $last_name_up,
                        "Address1" => $data['billing_address'],
                        "Address2"=> "",
                        "City"=> $data['city'],
                        "State"=> $data['state'],
                        "Zipcode"=> $data['zip'],
                        "Country"=> "US",
                        "LimitWindow"=> "Lifetime",
//                        "UsageLimit"=> 999, 不设置就是无限制
                        "AmountLimit"=> $spend_limit,
                        "ExpirationDate"=> $exp_time,
                        "TerminateDate"=> $exp_time,
                        "PurchaseType"=> "98",
                        "SequenceNumber"=> "Sample-seq-1",
                        "OrderNumber"=> $card_memo,
                        "CustomerId"=>"Ken Pullin",
                        "MIDBlacklist"=>$key_array,
                        "NonDomesticSupplier"=> true,
                        "cardBin"=>getAllCard($card_type_new)
                    ]
                ];
                $create_card_api= PublicApi::requestApi('Connexpay',$create_card_param);
            }else{
                $create_card_param      = [
                    "user_id"       => $user_id,
                    "action_type"   => "addCard",
                    "card_type"     => $card_type_new,
                    "bank_type"     => $bank_type,
                    "post_param"  => [
                        "memo"              => $card_memo,
                        "first_name"        => $first_name_up,
                        "last_name"         => $last_name_up,
//                    "exp_time"          => date('Y-m-01',strtotime('next month +2 year'))
                        "exp_time"          => date('Y-m-01',strtotime('+23 month'))
                    ]
                ];
                $create_card_api= PublicApi::requestApi($cardHeaderType,$create_card_param);
            }
            $return_blog    = $create_card_api['blog'];
            $return_list    = $create_card_api['list'];

            if($return_blog){
                Db::startTrans();
                try{
                    $card_holder        = '';
                    $exp_date           = '';
                    $cvv                = '';
                    if($bank_type == 3){
                        $card_token         = $return_list['card']['cardGuid'];
                        $card_num           = $return_list['card']['accountNumber'];
                        $card_holder        = $return_list['cardHolder']['cardHolderGuid'];
                        $exp_date           = $return_list['card']['expiration'];
                        $cvv                = $return_list['card']['securityCode'];
                    }else{
                        $card_token         = $return_list['cardToken'];
                        $card_num           = $return_list['cardNumber'];
                    }
                    $card_num_4     = substr($card_num , -4);
                    $server_amount  = getSprintf(round($spend_limit*$server_amount_db ,2));
                    Db::name('cards')->save([
                        'user_id'           => $user_id,
                        'card_token'        => $card_token,
                        'memo'              => $card_memo,
                        'card_num'          => $card_num,
                        'first_name'        => $first_name,
                        'last_name'         => $last_name,
                        'first_name_up'     => $first_name_up,
                        'last_name_up'      => $last_name_up,
                        'middle_name'       => $middle_name,
                        'balance'           => $spend_limit,
                        'balance_account'   => $spend_limit,
                        'open_amount'       => $open_amount,
                        'server_amount'     => $server_amount,
                        'status'            => 1, //1 = active; 2 = blocked; 3 = clear;
                        'departments_id'    => $data['departments_id'] ?? '',
                        'remarks'           => $remarks,
                        'card_type'         => $card_type_new,
                        'ctime'             => $create_time,
                        'bank_type'         => $bank_type,
                        'card_holder_guid'  => $card_holder,
                        'check_status'      => ($bank_type == 3) ? 1 : 0,
                        'exp_date'          => ($bank_type == 3) ? $exp_date : '',
                        'cvv'               => ($bank_type == 3) ? $cvv : '',
                    ]);
                    //卡详情
                    $search = array('*','$','\\','/','%');
                    $billing_address = str_replace('&', 'and', $data['billing_address']);
                    $billing_address = str_replace($search, '',$billing_address);

                    Db::name('cards_detail')->save([
                        'memo'              => $card_memo,
                        'city'              => $data['city'] ?? '',
                        'state'             => $data['state'] ?? '',
                        'zip'               => $data['zip'] ?? '',
                        'remarks'           => $data['remark'] ?? '',
                        'billing_address'   => $billing_address,
                        'ctime'             => $create_time
                    ]);
                    //记录卡交易记录
                    Db::name('cards_log')->save([
                        'card_token' => $card_token,
                        'amount'     => $spend_limit,
                        'balance'    => $spend_limit,
                        'type'       => 1,  //1=建卡
                        'desc'       => "创建卡 {$card_type_new} *** " . $card_num_4,
                        'card_type'  => $card_type_new,
                        'ctime'      => $create_time
                    ]);
                    //更新用户余额
                    $current_user_balance= Db::name('user')->where(['id' => $user_id])->value('balance');
                    $update_balance      = $current_user_balance - $spend_limit;  //变化后余额
                    //记录钱包记录
                    Db::name('user_cash_log')->save([
                        'user_id'       => $user_id,
                        'type'          => 1, //1=debit
                        'action_type'   => 3, //3=消费
                        'amount'        => $spend_limit,
                        'balance'       => $update_balance, //如果是进行修复的话，这里的余额要重新计算
                        'desc'          => "创建卡 {$card_type_new} *** " . $card_num_4,
                        'card_type'     => $card_type_new,
                        'ctime'         => $create_time
                    ]);
                    //记录钱包开卡费
                    $update_balance_open = $update_balance - $open_amount;
                    Db::name('user_cash_log')->save([
                        'user_id'       => $user_id,
                        'type'          => 1, //1=debit
                        'action_type'   => 3, //3=消费
                        'amount'        => $open_amount,
                        'balance'       => $update_balance_open, //如果是进行修复的话，这里的余额要重新计算
                        'desc'          => "开卡费 {$card_type_new} *** " . $card_num_4,
                        'card_type'     => $card_type_new,
                        'ctime'         => $create_time + 2
                    ]);
                    //记录钱包开卡服务费
                    $update_balance_server  = $update_balance_open - $server_amount;
                    Db::name('user_cash_log')->save([
                        'user_id'       => $user_id,
                        'type'          => 1, //1=debit
                        'action_type'   => 3, //3=消费
                        'amount'        => $server_amount,
                        'balance'       => $update_balance_server, //如果是进行修复的话，这里的余额要重新计算
                        'desc'          => "充值服务费 ({$card_type_new} *** {$card_num_4})",
                        'card_type'     => $card_type_new,
                        'ctime'         => $create_time + 3
                    ]);
                    Db::name('user')->where(['id'=>$user_id])->update(['balance' => $update_balance_server]);
                    //记录用户操作
                    $logModel = new UserLog();
                    $logModel->setLog($user_id , 'create_card' , [
                        'card_num'      => $card_num ,
                        'card_balance'  => '$' . $spend_limit,
                        'card_memo'     => $card_memo
                    ]);
                    Db::commit();
                    $success_num += 1;
                } catch (\Exception $e) {
                    Cache::store('redis')->delete('user_balance_' . $user_name);
                    $error_msg  = $e->getMessage();
                    Db::name('api_error')->save([
                        'user_id'       => $user_id,
                        'amount'        => $spend_limit,
                        'amount_bank'   => $spend_limit,
                        'type'          => 'add_card',
                        'data_param'    => $error_msg,
                        'ctime'         => getUtcTime()
                    ]);
                    Db::rollback();
                    break;
                }
            }
        }
        Cache::store('redis')->delete('user_balance_' . $user_name);
        if($success_num > 0){
            return $success_num;
        }else{
            return false;
        }
    }

    /**
     * 更新卡状态
     * @param $data
     * @return bool|int
     */
    public static function changeCardStatus($data)
    {
        $id_array   = $data['id_array'];
        $type       = $data['type'];
        $user_id    = $data['user_id'];
        $user_name  = Db::name('user')->where(['id'=>$user_id])->value('username');
        $success_num =0;
        foreach ($id_array as $v){
            $card_id    = $v;
            $info       = Db::name('cards')->where("is_del !=1 and is_action =0")->find($card_id);
            if($info){
                $card_num   = substr($info['card_num'], -4);
                $card_type  = $info['card_type'];
                $bank_type  = $info['bank_type'];
                $card_token = $info['card_token'];
                $card_balance = $info['balance'];

                //卡状态：[ OPEN,PAUSED,CLOSED ]
                $type_api       = "";
                $change_status  = "";
                switch ($type){
                    case 'active':
                        $type_api       = 'card_active';
                        $change_status  = "1";
                        if($card_balance < 0){
                            return false;
                        }
                        break;
                    case 'suspended':
                        $type_api       = 'card_suspended';
                        $change_status  = "2";
                        break;
                }
                if(!$type_api){
                    return false;
                }
                if($bank_type == 3){
                    $data       = [
                        "user_id"       => $user_id,
                        "action_type"   => $type_api,
                        "cardGuid"      => $card_token,
                        "card_num"      => $info['card_num'],
                        "request_data"  => [
                            "Activated" => ($type_api == 'card_active') ? true : false
                        ]
                    ];
                    $update_result = PublicApi::requestApi('Connexpay' , $data);
                }else{
                    $data       = [
                        "user_id"       => $user_id,
                        "action_type"   => $type_api,
                        "card_type"     => $card_type,
                        "bank_type"     => $bank_type,
                        "post_param"    => [
                            "card_num"       => $info['card_num']
                        ]
                    ];
                    $update_result = PublicApi::requestApi('Comdata' , $data);
                }
                $update_result_blog = $update_result['blog'];
                if($update_result_blog){
                    $update_where = [
                        'status'=>  $change_status,
                        'utime' =>  getUtcTime()
                    ];
                    //更新卡列表状态
                    Db::name('cards')->where(['id'=> $card_id])->update($update_where);
                    //记录会员操作日志
                    $logModel = new UserLog();
                    $logModel->setLog($user_id , $type_api , ['card_num' => $card_num]);
                    $success_num += 1;
                }
            }
        }
        return $success_num;
    }

    public function setCardBalance($type,$data)
    {
        $card_id    = $data['card_id'];
        $amount     = $data['amount'];
        $user_id    = $data['user_id'];

        //获取当前用户余额
        $user_list              = Db::name('user')->find($user_id);
        $user_balance           = $user_list['balance'];
        $user_name              = $user_list['username'];
        //增加进程是否开始，防止重复建卡 //并且时间时间是10秒
        $redis_key              = 'user_update_balance_' . $user_name;
        Cache::store('redis')->set($redis_key , getUtcTime() , 10);
        //可能有卡消费了 ，需要再通过接口查询一下卡余额；
        comCardsModel::checkCardBalanceApi($card_id);
        //这里可能卡余额更新了 再查询一次卡信息
        $card_list              = Db::name('cards')->find($card_id);

        $card_balance           = $card_list['balance'];    //当前卡可用余额
        $balance_account        = $card_list['balance_account'];//当前卡账户余额
        $card_num               = $card_list['card_num'];
        $card_num4              = substr($card_num , -4);
        $card_token             = $card_list['card_token'];
        $is_del                 = $card_list['is_del'];
        $card_type              = $card_list['card_type'];
        $card_server_amount     = $card_list['server_amount'];
        $bank_type              = $card_list['bank_type'];

        $ctime                  = getUtcTime();
        if($is_del == 1){
            Cache::store('redis')->delete($redis_key);
            return false;
        }
        //获取卡操作记录的最近的一笔卡限额
        $card_amount_limit_list = Db::name('cards_log')->where(['card_token' => $card_token])->order('id desc')->find();
        $card_amount_limit      = $card_amount_limit_list['balance'];
        //卡列表记录的卡限额 和 卡操作记录的卡限额不一致 返回失败
        if($balance_account - $card_amount_limit !=0){
            Cache::store('redis')->delete($redis_key);
            if($bank_type == 3){
                $data       = [
                    "user_id"       => $user_id,
                    "action_type"   => "card_suspended",
                    "cardGuid"      => $card_token,
                    "card_num"      => $card_num,
                    "request_data"  => [
                        "Activated" => false
                    ]
                ];
                $update_result = PublicApi::requestApi('Connexpay' , $data);
            }else{
                $data       = [
                    "user_id"       => $user_id,
                    "action_type"   => "card_suspended",
                    "card_type"     => $card_type,
                    "bank_type"     => $bank_type,
                    "post_param"    => [
                        "card_num"       => $card_num
                    ]
                ];
                $update_result = PublicApi::requestApi('Comdata' , $data);
            }
            $update_result_blog = $update_result['blog'];
            $ice_success = false;
            if($update_result_blog){
                $update_where = [
                    'status'    => 2,
                    'is_action' => 1,   //is_action  = 1 冻结后不能激活 | = 0 默认
                    'utime' =>  getUtcTime()
                ];
                //更新卡列表状态
                Db::name('cards')->where(['id'=> $card_id])->update($update_where);
                $ice_success = true;
                //记录会员操作日志
                $logModel = new UserLog();
                $logModel->setLog($user_id , "card_suspended" , [
                    'card_num' => $card_num ,
                    'desc'=>'卡操作记录卡限额和卡列表记录不一致',
                    'amount' =>  $balance_account . '___' . $card_amount_limit
                ]);
            }
            Db::name('action_error')->save([
                'user_id' => $user_id,
                'type'    => $type,   //类型场景
                'card_num'=> $card_num,
                'remark'  => '卡操作记录卡限额和卡列表记录不一致',
                'desc'    =>
                    "balance_account:{$balance_account} , 
                    card_amount_limit:{$card_amount_limit},
                    ice_result:{$ice_success}", //冻结接口结果
                'ctime'   => $ctime
            ]);
            return false;
        }

        $error_msg              = '';
        $blog                   = false;

        //deduct|add CardBalance
        if($type == 'add_card_balance'){
            $result_user_balance    = $user_balance - $amount;
            $result_card_balance    = $card_balance + $amount;
            $result_account_balance = $balance_account + $amount;
            $desc                   = "增加卡({$card_type} *** {$card_num4})余额";
            $card_log_type          = 2; //2-增加余额;3-减少余额
            $user_cash_log_type     = 1; //类型 0,Credit|1,Debit
        }else{
            $result_user_balance    = $user_balance + $amount;
            $result_card_balance    = $card_balance - $amount;
            if($result_card_balance <= 0){
                Cache::store('redis')->delete($redis_key);
                return false;
            }
            $result_account_balance = $balance_account - $amount;
            $desc                   = "减少卡({$card_type} *** {$card_num4})余额";
            $card_log_type          = 3;
            $user_cash_log_type     = 0;
        }

        if($bank_type == 1 || $bank_type ==2){
            $update_card_param      = [
                "user_id"       => $user_id,
                "action_type"   => $type,
                "card_type"     => $card_type,
                "bank_type"     => $bank_type,
                "post_param"  => [
                    "card_num"              => $card_num,
                    "card_balance"          => getSprintf(round($result_account_balance, 2))
                ]
            ];
            $create_card_api= PublicApi::requestApi('Comdata',$update_card_param);
            $return_blog    = $create_card_api['blog'];
            if(!$return_blog){
                $error_msg   = 'bank12 api request error';
            }
        }else if($bank_type == 3){
            $update_card_param      = [
                "user_id"       => $user_id,
                "action_type"   => $type,
                "card_num"      => $card_num,
                "cardGuid"      => $card_token,
                "request_data"  => [
                    "AmountLimit" => getSprintf(round($result_account_balance, 2))
                ]
            ];
            $create_card_api= PublicApi::requestApi('Connexpay',$update_card_param);
            $return_blog    = $create_card_api['blog'];
            if(!$return_blog){
                $error_msg   = 'bank3 api request error';
            }
        }else{
            $return_blog = false;
            $error_msg   = 'no find bank type';
        }
        if($return_blog){
            Db::startTrans();
            try{
                //记录卡总金额变化
                Db::name('cards_log')->save([
                    'card_token' => $card_token,
                    'amount' => $amount,
                    'balance' => $result_account_balance,
                    'type' => $card_log_type,
                    'desc' => $desc,
                    'card_type' => $card_type,
                    'ctime' => $ctime
                ]);
                //记录钱包记录
                Db::name('user_cash_log')->save([
                    'user_id' => $user_id,
                    'type' => $user_cash_log_type,
                    'action_type' => 5, //3=消费
                    'amount' => $amount,
                    'balance' => $result_user_balance,
                    'desc' => $desc,
                    'card_type' => $card_type,
                    'ctime' => $ctime
                ]);
                if ($type == 'add_card_balance') {
                    $rate = $data['rate'];
                    $server_amount = $amount * $rate;
                    $result_user_balance -= $server_amount;
                    $card_server_amount += $server_amount;
                    //做精度处理
                    $result_user_balance = getSprintf(round($result_user_balance, 2));

                    //记录钱包卡充值服务费记录
                    Db::name('user_cash_log')->save([
                        'user_id' => $user_id,
                        'type' => $user_cash_log_type,
                        'action_type' => 5, //3=消费
                        'amount' => $server_amount,
                        'balance' => $result_user_balance,
                        'desc' => "充值服务费 ({$card_type} *** {$card_num4})",
                        'card_type' => $card_type,
                        'ctime' => $ctime
                    ]);
                }
                //做精度处理
                $card_server_amount = getSprintf(round($card_server_amount, 2));
                $result_user_balance = getSprintf(round($result_user_balance, 2));
                $result_card_balance = getSprintf(round($result_card_balance, 2));

                //更新公司用户余额
                Db::name('user')->where([
                    'id' => $user_id
                ])->update(['balance' => $result_user_balance]);
                //更新卡余额
                Db::name('cards')->where([
                    'id' => $card_id
                ])->update([
                    'balance'           => $result_card_balance,
                    'balance_account'   => $result_account_balance,
                    'server_amount'     => $card_server_amount
                ]);
                $blog = true;
                Db::commit();
            } catch (\Exception $e) {
                Cache::store('redis')->delete($redis_key);
                $blog       = false;
                $error_msg  = $e->getMessage() . '---' . $e->getLine();
                Db::rollback();
            }
        }
        if(!$blog){
            Db::name('index_error')->save([
                'user_id'       => $user_id,
                'amount'        => $amount,
                'type'          => $type,
                'card_num'      => $card_num,
                'data_param'    => (empty($error_msg) ? "" : "error:{$error_msg}"),
                'desc'          => json_encode([
                    "end_amount_user" => $result_user_balance,
                    "end_amount_card" => $result_card_balance
                ]),
                'ctime'         => getUtcTime()
            ]);
        }
        //记录用户操作
        $logModel = new UserLog();
        $logModel->setLog($user_id, $type,
            ['result' => $blog ,
                'card_num'  => $card_num,
                'amount'    => $amount ,
                'end_amount_user' =>  $result_user_balance,
                'end_amount_card' =>  $result_card_balance,
                'error'=> empty($error_msg) ? "" : "error:{$error_msg}"
            ]);
        Cache::store('redis')->delete($redis_key);
        return $blog;
    }

    public function getCardSet($user_id)
    {
        $list = Db::name('user_set')->where(['user_id' => $user_id])
            ->order('type')->find();
        if(empty($list)){
            $type  = Db::name('user')->where(['id' => $user_id])->value('grade');
            //grade = 2时候，事管理员认证用户， 那么user_set 中type=1就按用户认证状态算
            if($type == 2){
                $type =1;
            }
            $list = Db::name('user_set')->where(['type' => $type , 'user_id'=>0])->find();
        }
        return $list;
    }

    public function setCardRemarks($data)
    {
        $card_id    = $data['card_id'];
        $remarks    = $data['remarks'];
        //$departments_id = $data['departments_id'];
        $user_id    = $data['user_id'];

        $card_list  = $this->find($card_id);
        $card_num   = $card_list['card_num'];
        $card_list['remarks']        = $remarks;
        //$card_list['departments_id'] = $departments_id;
        $result     = $card_list->save();

        //记录用户操作
        $logModel = new UserLog();
        $logModel->setLog($user_id , "card set remarks" ,
            ['card_num' => $card_num,'remarks' =>$remarks ]);

        return $result;
    }

    public static function setCardCancel($data)
    {
        $card_id    = $data['card_id'];
        $user_id    = $data['user_id'];
        $bank_type  = $data['bank_type'];

        //获取当前用户余额
        $user_list              = Db::name('user')->find($user_id);
        $user_balance   = $user_list['balance'];
        $user_name              = $user_list['username'];

        //可能有卡消费了 ，需要再通过接口查询一下卡余额；
        comCardsModel::checkCardBalanceApi($card_id);
        //这里可能卡余额更新了 再查询一次卡信息
        $card_list              = Db::name('cards')->find($card_id);

        $card_balance           = $card_list['balance'];
        $account_balance        = $card_list['balance_account'];
        $card_num               = $card_list['card_num'];
        $card_token             = $card_list['card_token'];
        $card_type              = $card_list['card_type'];

        $ctime                  = getUtcTime();
        $blog                   = false;

        $redis_key              = 'user_update_balance_' . $user_name;
        Cache::store('redis')->set($redis_key , getUtcTime() , 10);

        if($bank_type == 3){
            $re_account_balance =  $account_balance - $card_balance;
            $AmountLimit        =  1;
            if($re_account_balance >0){
                //卡总金额比卡余额大 说明卡有消费，这时卡剩余的卡总金额就是已消费金额，这里要更新卡金额限制
                $AmountLimit        =  $re_account_balance;
            }
            $api_3_param      = [
                "user_id"       => $user_id,
                "action_type"   => "del_up_card",
                "card_num"      => $card_num,
                "cardGuid"      => $card_token,
                "request_data"  => [
                    "AmountLimit" => getSprintf(round($AmountLimit,2))
                ]
            ];
            $res_1 = PublicApi::requestApi('Connexpay',$api_3_param);
            $re_1_blog = $res_1['blog'] ?? false;
            if($re_1_blog){
                $update_card_param      = [
                    "user_id"       => $user_id,
                    "action_type"   => "card_del",
                    "card_num"      => $card_num,
                    "cardGuid"      => $card_token
                ];
                $create_card_api= PublicApi::requestApi('Connexpay',$update_card_param);
                $re_blog = $create_card_api['blog'] ?? false;
                if(!$re_blog){
                    $error_msg = "(del_card)bank3 api request error";
                }
            }else{
                $error_msg = "(del_card_up_balance)bank3 api request error";
            }

        }else{
            //卡总金额比卡余额大 说明卡有消费
            if(($account_balance - $card_balance) > 0){
                $action_type = 'card_del_unReal';   //软删除，更新卡状态为B=BLOCKED，冻结
            }else{
                $action_type = 'card_del';          //删除，更新卡状态为C=CLERR，删除
            }
            $update_card_param      = [
                "user_id"       => $user_id,
                "action_type"   => $action_type,
                "card_type"     => $card_type,
                "bank_type"     => $bank_type,
                "post_param"  => [
                    "card_num"  => $card_num
                ]
            ];
            $create_card_api= PublicApi::requestApi('Comdata',$update_card_param);
            $re_blog = $create_card_api['blog'] ?? false;
            if(!$re_blog){
                $error_msg = "bank12 api request error";
            }
        }
        $return_blog    = $create_card_api['blog'];
        if($return_blog){
            Db::startTrans();
            try{
                $desc = "删除卡(**** " . substr($card_num , -4) . ")";
                $result_user_balance    =   $user_balance + $card_balance;
                $result_account_balance =   $account_balance - $card_balance;
                if($bank_type != 3){
                    if($result_account_balance >0){
                        //卡总金额比卡余额大 说明卡有消费，这时卡剩余的卡总金额就是已消费金额，这里要更新卡金额限制
                        $update_card_param_unreal   = [
                            "user_id"       => $user_id,
                            "action_type"   => 'updateCardLimits',
                            "card_type"     => $card_type,
                            "bank_type"     => $bank_type,
                            "post_param"  => [
                                "card_balance"  => $result_account_balance,
                                "card_num"      => $card_num,
                            ]
                        ];
                        PublicApi::requestApi('Comdata',$update_card_param_unreal);
                    }
                }

                Db::name('user')->where(['id'=>$user_id])->update(['balance' => $result_user_balance]);
                $update_card_where = [
                    'balance'           => 0,
                    'balance_account'   => $result_account_balance,
                    'status'            => 3,
                    'is_del'            => ($result_account_balance >0)?1:0, //卡总金额比卡余额大 说明卡有消费,软删除is_del=1
                    'utime'             => $ctime
                ];
                Db::name('cards')->where(['id'=>$card_id])->update($update_card_where);
                //记录卡交易记录
                Db::name('cards_log')->save([
                    'card_token' => $card_token,
                    'card_type'  => $card_type,
                    'amount'     => $card_balance,
                    'balance'    => $result_account_balance,
                    'type'       => 4,
                    'desc'       => $desc,
                    'ctime'      => $ctime
                ]);
                //记录钱包记录
                Db::name('user_cash_log')->save([
                    'user_id'       => $user_id,
                    'type'          => 0,
                    'action_type'   => 4, //3=消费
                    'amount'        => $card_balance,
                    'balance'       => $result_user_balance,
                    'desc'          => $desc,
                    'card_type'     => $card_type,
                    'ctime'         => $ctime
                ]);
                $blog = true;
                Db::commit();
            } catch (\Exception $e) {
                Cache::store('redis')->delete($redis_key);
                $error_msg  = $e->getMessage() . '---' . $e->getLine();
                Db::name('api_error')->save([
                    'user_id'       => $user_id,
                    'amount'        => $card_balance,
                    'amount_bank'   => $card_balance,
                    'type'          => 'card_del',
                    'data_param'    => $e->getMessage(),
                    'ctime'         => getUtcTime()
                ]);
                $blog = false;
                Db::rollback();
            }
        }
        if(!$blog){
            Db::name('index_error')->save([
                'user_id'       => $user_id,
                'amount'        => $card_balance,
                'type'          => "card_del",
                'card_num'      => $card_num,
                'data_param'    => (empty($error_msg) ? "" : "error:{$error_msg}"),
                'ctime'         => getUtcTime()
            ]);
        }
        //记录用户操作
        $logModel = new UserLog();
        $logModel->setLog($user_id , "card del" ,
            ['card_num' => $card_num , 'result'=> $blog ,  'amount' => '$ ' . $card_balance]);
        //删除删卡进程
        Cache::store('redis')->delete($redis_key);
        return $blog;
    }

//-----------------------------------------后端-------------------------------------------------
    /**
     * 返回layui的table所需要的格式
     * @param $post
     * @param $user_id
     * @return mixed
     * @throws \think\db\exception\DbException
     */
    public function tableDataAdmin($post)
    {
        $list_rows  = $post['limit'] ?? config('paginate.list_rows');
        $page       = $post['page'] ?? config('paginate.page');

        $where =[];
        if(isset($post['username']) && !empty($post['username'])){
            $where[] = ['username', 'like', '%'.$post['username'].'%'];
        }
        if(isset($post['card_num']) && !empty($post['card_num'])){
            $where[] = ['card_num', 'like', '%'.$post['card_num'].'%'];
        }
        if(isset($post['card_token']) && !empty($post['card_token'])){
            $where[] = ['card_token', 'like', '%'.$post['card_token'].'%'];
        }
        if(isset($post['datetime']) && !empty($post['datetime'])){
            $time_list = explode('_' , $post['datetime']);
            $start_time = strtotime($time_list[0] . " 00:00:00") - 8*60*60;
            $end_time   = strtotime($time_list[1] . " 23:59:59") - 8*60*60;
            $where[] = ['c.ctime', 'between', "{$start_time},{$end_time}"];
        }
        $list = Db::name('cards')->alias('c')
            ->leftJoin('user u' ,'u.id=c.user_id')
            ->leftJoin('cards_product cp' ,'cp.id=c.cards_product_id')
            ->where($where)
            ->field('c.id,username,cp.product_token,c.status,c.first_name,c.last_name,card_num,c.balance,c.ctime,expiration_time,remarks,card_token')
            ->order('c.ctime desc')
            ->paginate(['list_rows' => $list_rows, 'page' => $page])
            ->toArray();

        return $result = [
            'code'  => 0,
            'msg'   => lang('get info success'),
            'data'  => $list['data'],
            'count' => $list['total'],
        ];
    }

    public static function changeCardLimit($data)
    {
        $id_array   = $data['id_array'];
        $user_id    = $data['user_id'];
        $amount     = $data['amount'];
        $success_num =0;
        if(!is_array($id_array)){
            $id_array = explode("," , $id_array);
        }
        foreach ($id_array as $v) {
            $card_id = $v;
            $info       = Db::name('cards')->find($card_id);
            $card_num   = substr($info['card_num'], -4);
            //更新卡列表状态
            Db::name('cards')->where(['id'=> $card_id])->update(['account_balance' => $amount]);
            //记录会员操作日志
            $logModel = new UserLog();
            $logModel->setLog($user_id , 'edit_card_limit' , ['card_num' => $card_num]);
            $success_num += 1;
        }
        return $success_num;
    }

    public static function changeCardDepartment($data)
    {
        $id_array   = $data['id_array'];
        $user_id    = $data['user_id'];
        $department = $data['department'];

        $success_num =0;
        if(!is_array($id_array)){
            $id_array = explode("," , $id_array);
        }
        foreach ($id_array as $v) {
            $card_id = $v;
            $info       = Db::name('cards')->find($card_id);
            $card_num   = substr($info['card_num'], -4);
            //更新卡列表状态
            Db::name('cards')->where(['id'=> $card_id])->update(['departments_id' => $department]);
            //记录会员操作日志
            $logModel = new UserLog();
            $logModel->setLog($user_id , 'edit_card_department' , ['card_num' => $card_num,'departments_id'=>$department]);
            $success_num += 1;
        }
        return $success_num;
    }

    public static function changeCardAddress($data)
    {
        $user_id        = $data['user_id'];
        $card_id        = $data['card_id'];
        $billing_address= $data['billing_address'];
        $city           = $data['city'];
        $state          = $data['state'];
        $zip            = $data['zip'];

        $card_list      = Db::name('cards')->find($card_id);
        $card_type      = $card_list['card_type'];
        $card_num       = $card_list['card_num'];
        $memo           = $card_list['memo'];
        $bank_type      = $card_list['bank_type'];

        if($bank_type != 3){
            //更新卡地址
            $upCardParam =[
                "user_id"       => $user_id,
                "action_type"   => "updateCard",
                "card_type"     => $card_type,
                "bank_type"     => $bank_type,
                "post_param"  => [
                    "card_num"  => $card_num,
                    "address"   => $billing_address,
                    "city"      => $city ,
                    "state"     => $state ,
                    "zip"       => $zip
                ]
            ];
            $upCardApi = PublicApi::requestApi('Comdata',$upCardParam);

            $up_card_blog = $upCardApi['blog'];
        }else{
            $up_card_blog = true;
        }

        if($up_card_blog) {
            try{
                return Db::name('cards_detail')->where(['memo'=>$memo])->update([
                    'billing_address'   => $billing_address,
                    'city'              => $city,
                    'state'             => $state,
                    'zip'               => $zip,
                    'utime'             => getUtcTime()
                ]);
            }catch (\Exception $e){
                return false;
            }
        }else{
            return false;
        }
    }

    public function updateCardLimit($type , $amount,$card_id ,$user_id)
    {
        $list       = Db::name('cards')->find($card_id);
        //卡账户余额(共享模式下account_balance=Spend Limit 卡限额)
        $balance_spend      = $list['balance_spend'];
        $card_token         = $list['card_token'];
        $balance_used       = $list['balance_used'];
        //$limit_token        = $list['limit_token'];
        if($type == 'add'){
            $balance_spend += $amount;
            $cards_log_type = 2;
        }else{
            $balance_spend -= $amount;
            $cards_log_type = 3;
        }
        //记录卡交易记录
        Db::name('cards_log')->save([
            'card_token'    => $card_token,
            'amount'        => $balance_used,         //已用金额
            'balance'       => $balance_spend,   //限额
            'type'          => $cards_log_type,
            'desc'          => $type . ' Card Spend Limit $ ' . $amount,
            'ctime'         => getUtcTime()
        ]);
        $up_result = Db::name('lc_cards')->where(['id' => $card_id])
            ->update([
                'balance_spend'   => $balance_spend,
            ]);
        if($up_result){
            return true;
        }else{
            return false;
        }
    }
}